iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

學習筆記系列 第 14

java 執行緒 Scatter Gather pattern

  • 分享至 

  • xImage
  •  

記錄學習內容。看網路上大大們的文章和影片,做些紀錄。
把這邊當作寫筆記的地方,內容可能有錯誤。

教學來源:
Java Concurrency Interview: Implement Scatter Gather pattern

情況:同時3個http執行緒執行,然後忽略3秒內沒完成http request的執行緒。

影片裡教了三種方法:
第一種方式 : threadPool和 thread.sleep
第二種方式 : CountDownLatch 和 latch.await
第三種方式 : CompletableFuture.runAsync

程式來自影片:
像是現在有3個http request 要去爬蟲 ,3秒內沒爬到的就不理。

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;

public class ThreadTest9 {

    static ExecutorService threadPool = Executors.newFixedThreadPool(4);

    //CountDownLatch  和 threadPool.submit
    private static Set<Integer> getPrices(int productId) throws InterruptedException {

        Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());

        CountDownLatch latch = new CountDownLatch(3);

        threadPool.submit(new Task("google", productId, prices, latch));
        threadPool.submit(new Task("fb", productId, prices, latch));
        threadPool.submit(new Task("twitter", productId, prices, latch));

        // Thread.sleep(3*1000);
        //   latch.await();
        latch.await(3, TimeUnit.SECONDS); //3 seconds  或是 CountDownLatch變成0
        System.out.println("finished getPrices" + prices);
        return prices;
    }

    //CompletableFuture
    private static Set<Integer> getPrices1(int productId) throws InterruptedException, TimeoutException, ExecutionException {

        Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());

        CompletableFuture<Void> task1 = CompletableFuture.runAsync(new Task("google", productId, prices));
        CompletableFuture<Void> task2 = CompletableFuture.runAsync(new Task("fb", productId, prices));
        CompletableFuture<Void> task3 = CompletableFuture.runAsync(new Task("twitter", productId, prices));

        CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);

        allTasks.get(3, TimeUnit.SECONDS);
        System.out.println("finished getPrices1" + prices);
        return prices;
    }

    //執行緒
    private static class Task implements Runnable {

        private String url;
        private int productId;
        private Set<Integer> prices;
        private CountDownLatch latch;

        public Task(String url, int productId, Set<Integer> prices, CountDownLatch latch) {
            this.url = url;
            this.productId = productId;
            this.prices = prices;
            this.latch = latch;
        }

        public Task(String url, int productId, Set<Integer> prices) {
            this.url = url;
            this.productId = productId;
            this.prices = prices;
            //this.latch = latch;
        }

        @Override
        public void run() {
            int price = (int) (Math.random() * 100) + 1;
            prices.add(price);
            try {
                //Thread.sleep(2000);  // 沒有timeout
                 Thread.sleep(4000); // 有timeout
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //  System.out.println("prices:" + prices);
            if (latch != null)
                latch.countDown();
        }
    }


    public static void main(String args[]) throws TimeoutException, ExecutionException {
        try {
            getPrices(5);
            getPrices1(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }


}

結果(時間內沒完成):

finished getPrices[55, 75, 45]
Exception in thread "main" java.util.concurrent.TimeoutException
	at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
	at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
	at ThreadTest9.getPrices1(ThreadTest9.java:39)
	at ThreadTest9.main(ThreadTest9.java:87)

結果(時間內完成):

finished getPrices[64, 4, 9]
finished getPrices1[7, 59, 95]

上一篇
HSV色彩空間
下一篇
協程 (coroutine)
系列文
學習筆記46
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言